from flask import Blueprint, render_template, request, redirect, url_for, session, jsonify
import requests
import re
import time
import threading
from flask_login import login_required, current_user
from app.services.movie_service import MovieService

# 创建蓝图
movie_bp = Blueprint('movie', __name__, url_prefix='/movie')

# 缓存相关
_categories_cache = {
    'data': {
        'liangzi':None,
        'haohua':None,
        'feifan':None
    },
    'timestamp': 0,
    'lock': threading.Lock()
}
CACHE_LIFETIME = 7200  # 2小时缓存有效期（秒）

# 获取影视API配置
def get_movie_api():
    """
    获取当前选择的影视API URL
    默认为量子
    """
    resources = MovieService.get_resources_for_api()

    api_url = resources[0]['url']  # 使用第一个资源作为默认API URL
    session['playurl'] = resources[0]['play_url'] # 默认播放器
    
    # 使用前端传过来的
    name = request.args.get('name')
    print(f"reqname: {name}")
    if name:
        for resource in resources:
            if resource['name'] == name:
                api_url = resource['url'] # 指定选择API
                session['playurl'] = resource['play_url'] # 指定选择播放器
                print(f"reqapi_url: {api_url}")
                break  # 找到匹配项后跳出循环

    return api_url

# 获取分类数据
def get_categories(currentname):
    current_time = time.time()

    # 判断currentname是否为空,设置默认值为liangzi
    if not currentname:
        currentname = 'liangzi'
    
    # 检查缓存是否有效
    with _categories_cache['lock']:
        if (_categories_cache['data'][currentname] is not None and 
            current_time - _categories_cache['timestamp'] < CACHE_LIFETIME):
            print("从缓存获取分类数据")
            return _categories_cache['data'][currentname]
    
    # 缓存无效，从API获取新数据
    api_url = get_movie_api()
    try:
        # 获取电影分类数据
        print("从API获取分类数据")
        response = requests.get(f"{api_url}?ac=list")
        if response.status_code == 200:
            data = response.json()
            if data.get('code') == 1 and 'class' in data:
                # 更新缓存
                with _categories_cache['lock']:
                    _categories_cache['data'][currentname] = data['class']
                    _categories_cache['timestamp'] = current_time
                return data['class']
    except Exception as e:
        print(f"获取分类失败: {e}")
    
    # 如果获取失败但有缓存，使用过期缓存
    with _categories_cache['lock']:
        if _categories_cache['data'][currentname] is not None:
            print("使用过期缓存数据")
            return _categories_cache['data'][currentname]
    
    return []

# 刷新分类缓存
def refresh_categories_cache(currentname):
    with _categories_cache['lock']:
        _categories_cache['data'][currentname] = None
        _categories_cache['timestamp'] = 0
    # 获取新数据
    get_categories(currentname)

# 处理URL，确保是完整的URL
def ensure_full_url(url):
    if not url:
        return url_for('static', filename='images/error.png') # 默认图片
    
    # 如果是相对URL或特殊格式，转换为完整URL
    if not url.startswith(('http://', 'https://')):
        url = "https:" + url if url.startswith('//') else "http://" + url
    
    return url

# 处理搜索结果和分类结果
def process_movies_data(api_url, params=None):
    if params is None:
        params = {}
    
    try:
        print(f"请求开始: {api_url}, {params}" ) 
        start_time = time.perf_counter()  # 高精度计时
        response = requests.get(api_url, params=params)
        end_time = time.perf_counter()
        print(f"请求耗时: {end_time - start_time:.2f}秒, status_code: {response.status_code}")

        if response.status_code == 200:
            data = response.json()
            if data.get('code') == 1:
                movies = data.get('list', [])
                
                # 处理电影数据中的图片URL
                for movie in movies:
                    if 'vod_pic' in movie:
                        movie['vod_pic'] = ensure_full_url(movie['vod_pic'])
                
                return {
                    'movies': movies,
                    'total': data.get('total', 0),
                    'page': data.get('page', '1'),
                    'pagecount': data.get('pagecount', 1)
                }
    except Exception as e:
        print(f"获取影片数据失败: {e}")
    
    return {
        'movies': [],
        'total': 0,
        'page': '1',
        'pagecount': 1
    }

# 处理播放URL
def process_play_url(play_url):
    # 去除转义字符
    play_url = play_url.replace('\\/', '/')
    
    # 确保是完整的URL
    if not play_url.startswith(('http://', 'https://')):
        play_url = "https:" + play_url if play_url.startswith('//') else "http://" + play_url
        
    return play_url

# 首页和分类页 - 显示最新影片或分类影片
@movie_bp.route('/', defaults={'category_id': None})
@movie_bp.route('/category/<int:category_id>')
@login_required
def index(category_id):
    api_url = get_movie_api()
    params = {'ac': 'videolist', 'pg': request.args.get('pg', '1')}
    currentname = request.args.get('name', '')
    
    # 处理分类
    categories = get_categories(currentname)
    current_category = None
    subcategories = []
    parent_category_name = ""
    
    # 如果指定了分类ID，添加到查询参数
    if category_id:
        params['t'] = category_id
        current_category = category_id
        
        # 找到当前分类信息
        for category in categories:
            if int(category['type_id']) == category_id:
                # 如果是父分类，查找子分类
                if category['type_pid'] == 0:
                    parent_category_name = category['type_name']
                    subcategories = [c for c in categories if c['type_pid'] == category_id]
                # 如果是子分类，查找父分类名称
                else:
                    for parent in categories:
                        if int(parent['type_id']) == category['type_pid']:
                            parent_category_name = parent['type_name']
                            subcategories = [c for c in categories if c['type_pid'] == parent['type_id']]
                            break
                break
    
    # 获取影片列表
    data = process_movies_data(api_url, params)
    
    # 准备分页URL
    pagination_url = f"/movie/category/{category_id}?name={currentname}&t={category_id}" if category_id else f"/movie?name={currentname}"
    
    # 准备页面标题
    if category_id:
        list_title = f"{parent_category_name} - "
        for category in categories:
            if int(category['type_id']) == category_id:
                list_title += category['type_name']
                break
    else:
        list_title = "最新上线"
    
    # 获取所有可用影视资源
    resources = MovieService.get_resources_for_api()
    
    return render_template('movie/index.html', 
                          categories=categories,
                          subcategories=subcategories,
                          parent_category_name=parent_category_name,
                          current_category=current_category,
                          movies=data['movies'],
                          list_title=list_title,
                          total_pages=int(data['pagecount']),
                          current_page=int(data['page']),
                          pagination_url=pagination_url,
                          username=current_user.username,
                          resources=resources,
                          currentname=currentname)

# 搜索页
@movie_bp.route('/search')
@login_required
def search():
    keyword = request.args.get('wd', '')
    page = request.args.get('pg', '1')
    currentname = request.args.get('name', '')
    
    if not keyword:
        return redirect(url_for('movie.index'))
    
    api_url = get_movie_api()
    params = {
        'ac': 'videolist', # list 或videolist
        'wd': keyword,
        'pg': page
    }
    
    data = process_movies_data(api_url, params)
    categories = get_categories(currentname)
    
    # 准备分页URL
    pagination_url = f"/movie/search?name={currentname}&wd={keyword}"
    
    # 获取所有可用影视资源
    resources = MovieService.get_resources_for_api()
    
    return render_template('movie/index.html',
                          categories=categories,
                          subcategories=[],
                          parent_category_name="",
                          current_category=None,
                          movies=data['movies'],
                          list_title=f"搜索结果: {keyword}",
                          total_pages=int(data['pagecount']),
                          current_page=int(data['page']),
                          pagination_url=pagination_url,
                          keyword=keyword,
                          username=current_user.username,
                          resources=resources,
                          currentname=currentname)

# 影片详情页
@movie_bp.route('/detail/<int:movie_id>')
@login_required
def detail(movie_id):
    api_url = get_movie_api()
    currentname = request.args.get('name', '')
    params = {
        'ac': 'detail',
        'ids': movie_id
    }
    
    try:
        response = requests.get(api_url, params=params)
        if response.status_code == 200:
            data = response.json()
            if data.get('code') == 1 and data.get('list'):
                movie = data['list'][0]
                
                # 处理图片URL
                if 'vod_pic' in movie:
                    movie['vod_pic'] = ensure_full_url(movie['vod_pic'])
                
                # 处理播放列表
                play_list = []
                play_from = movie.get('vod_play_from', '')
                
                if play_from and movie.get('vod_play_url'):
                    play_urls = movie['vod_play_url'].split('#')
                    for i, url in enumerate(play_urls):
                        parts = url.split('$')
                        if len(parts) == 2:
                            play_list.append({
                                'index': i + 1,
                                'name': parts[0],
                                'url': process_play_url(parts[1])
                            })
                
                # 获取相关推荐（相同分类的影片）
                related_movies = []
                if movie.get('type_id'):
                    related_params = {
                        'ac': 'videolist',
                        't': movie['type_id'],
                        'pg': 1,
                        'limit': 12
                    }
                    related_data = process_movies_data(api_url, related_params)
                    related_movies = [m for m in related_data['movies'] if str(m['vod_id']) != str(movie_id)][:6]
                
                # 获取所有可用影视资源
                resources = MovieService.get_resources_for_api()
                
                return render_template('movie/detail.html',
                                      movie=movie,
                                      play_list=play_list,
                                      related_movies=related_movies,
                                      username=current_user.username,
                                      resources=resources,
                                      playurl=session.get('playurl', ''),
                                      currentname=currentname)
    
    except Exception as e:
        print(f"获取影片详情失败: {e}")
    
    # 如果获取失败，返回到列表页
    return redirect(url_for('movie.index'))

# 播放页面
@movie_bp.route('/play/<int:movie_id>/<int:episode_index>')
@login_required
def play(movie_id, episode_index):
    api_url = get_movie_api()
    currentname = request.args.get('name', '')
    params = {
        'ac': 'detail',
        'ids': movie_id
    }
    
    try:
        response = requests.get(api_url, params=params)
        if response.status_code == 200:
            data = response.json()
            if data.get('code') == 1 and data.get('list'):
                movie = data['list'][0]
                
                # 处理图片URL
                if 'vod_pic' in movie:
                    movie['vod_pic'] = ensure_full_url(movie['vod_pic'])
                
                # 处理播放列表
                play_list = []
                play_from = movie.get('vod_play_from', '')
                current_url = None
                
                if play_from and movie.get('vod_play_url'):
                    play_urls = movie['vod_play_url'].split('#')
                    for i, url in enumerate(play_urls):
                        parts = url.split('$')
                        if len(parts) == 2:
                            play_url = process_play_url(parts[1])
                            play_list.append({
                                'index': i + 1,
                                'name': parts[0],
                                'url': play_url
                            })
                            if i + 1 == episode_index:
                                current_url = play_url
                
                # 获取相关推荐（相同分类的影片）
                related_movies = []
                if movie.get('type_id'):
                    related_params = {
                        'ac': 'list',
                        't': movie['type_id'],
                        'pg': 1,
                        'limit': 12
                    }
                    related_data = process_movies_data(api_url, related_params)
                    related_movies = [m for m in related_data['movies'] if str(m['vod_id']) != str(movie_id)][:6]
                
                # 获取所有可用影视资源
                resources = MovieService.get_resources_for_api()
                
                return render_template('movie/detail.html',
                                      movie=movie,
                                      play_list=play_list,
                                      current_url=current_url,
                                      current_episode=episode_index,
                                      related_movies=related_movies,
                                      username=current_user.username,
                                      resources=resources,
                                      currentname=currentname)
    
    except Exception as e:
        print(f"获取播放数据失败: {e}")
    
    # 如果获取失败，返回到详情页
    return redirect(url_for('movie.detail', movie_id=movie_id)) 